import pymysql
from typing import List, Dict
from movie_dao import MovieDAO  # 假设你已经有了数据库配置文件

class MovieTypeDAO:
    """电影类型数据访问对象，用于处理电影类型的统计和分布"""
    
    def __init__(self):
        """初始化电影类型DAO对象"""
        # 复用 MovieDAO 的数据库配置
        self.movie_dao = MovieDAO()

    def get_movie_type_distribution(self) -> List[Dict[str, any]]:
        """
        获取电影类型分布数据
        返回格式: [{"value": count, "name": type_name}, ...]
        处理一部电影多个类型的情况，只返回前26种类型
        """
        try:
            # 获取数据库配置并设置字符编码
            db_config = self.movie_dao.db_config.copy()  # 复制数据库配置
            db_config.update({
                'charset': 'utf8mb4',  # 设置字符集为utf8mb4
                'use_unicode': True,  # 使用Unicode
                'init_command': 'SET NAMES utf8mb4',  # 初始化命令
                'collation': 'utf8mb4_unicode_ci'  # 设置排序规则
            })
            
            # 连接数据库
            conn = pymysql.connect(**db_config)  # 创建数据库连接
            cursor = conn.cursor(pymysql.cursors.DictCursor)  # 创建返回字典格式数据的游标

            # 设置连接的字符集
            cursor.execute('SET NAMES utf8mb4')  # 设置名称字符集
            cursor.execute('SET CHARACTER SET utf8mb4')  # 设置字符集
            cursor.execute('SET character_set_connection=utf8mb4')  # 设置连接字符集

            # SQL查询 - 使用子查询处理空格分隔的类型
            sql = """
            SELECT 
                CONVERT(genre USING utf8mb4) as name,  # 转换类型名称为utf8mb4编码
                COUNT(*) as value  # 统计每种类型的数量
            FROM (
                SELECT 
                    SUBSTRING_INDEX(SUBSTRING_INDEX(m.genre, ' ', numbers.n), ' ', -1) genre  # 分割类型字符串
                FROM
                    (SELECT 1 n UNION ALL  # 创建数字序列用于分割
                     SELECT 2 UNION ALL 
                     SELECT 3 UNION ALL 
                     SELECT 4 UNION ALL 
                     SELECT 5) numbers
                INNER JOIN movies m  # 连接电影表
                ON CHAR_LENGTH(m.genre) - CHAR_LENGTH(REPLACE(m.genre, ' ', '')) >= numbers.n - 1  # 确保有足够的分隔符
                WHERE m.genre != '' AND m.genre IS NOT NULL  # 过滤空值
            ) split_genres
            WHERE genre != ''  # 过滤空类型
            GROUP BY genre  # 按类型分组
            ORDER BY value DESC, genre  # 按数量降序和类型名排序
            LIMIT 20;  # 限制返回前26种类型
            """

            cursor.execute(sql)  # 执行SQL查询
            results = cursor.fetchall()  # 获取所有查询结果

            # 格式化结果：转换为前端需要的格式
            type_distribution = [
                {
                    "name": row["name"],  # 类型名称
                    "value": int(row["value"])  # 类型数量
                }
                for row in results
            ]

            return type_distribution  # 返回类型分布数据

        except Exception as e:  # 捕获所有可能的异常
            print(f"获取电影类型分布时出错: {str(e)}")  # 打印错误信息
            return []  # 发生错误时返回空列表

        finally:  # 确保资源正确释放
            if 'conn' in locals():  # 如果连接已创建
                cursor.close()  # 关闭数据库游标
                conn.close()  # 关闭数据库连接

    def get_movie_type_count(self) -> int:
        """获取电影类型总数"""
        try:
            # 获取数据库配置并设置字符编码
            db_config = self.movie_dao.db_config.copy()  # 复制数据库配置
            db_config.update({
                'charset': 'utf8mb4',  # 设置字符集为utf8mb4
                'use_unicode': True,  # 使用Unicode
                'init_command': 'SET NAMES utf8mb4',  # 初始化命令
                'collation': 'utf8mb4_unicode_ci'  # 设置排序规则
            })
            
            # 连接数据库
            conn = pymysql.connect(**db_config)  # 创建数据库连接
            cursor = conn.cursor()  # 创建数据库游标

            # 设置连接的字符集
            cursor.execute('SET NAMES utf8mb4')  # 设置名称字符集
            cursor.execute('SET CHARACTER SET utf8mb4')  # 设置字符集
            cursor.execute('SET character_set_connection=utf8mb4')  # 设置连接字符集

            # SQL查询：统计不同电影类型的数量
            sql = """
            SELECT COUNT(DISTINCT genre)  # 统计不同类型的数量
            FROM (
                SELECT 
                    SUBSTRING_INDEX(SUBSTRING_INDEX(m.genre, ' ', numbers.n), ' ', -1) genre  # 分割类型字符串
                FROM
                    (SELECT 1 n UNION ALL  # 创建数字序列用于分割
                     SELECT 2 UNION ALL 
                     SELECT 3 UNION ALL 
                     SELECT 4 UNION ALL 
                     SELECT 5) numbers
                INNER JOIN movies m  # 连接电影表
                ON CHAR_LENGTH(m.genre) - CHAR_LENGTH(REPLACE(m.genre, ' ', '')) >= numbers.n - 1  # 确保有足够的分隔符
                WHERE m.genre != '' AND m.genre IS NOT NULL  # 过滤空值
            ) split_genres
            WHERE genre != '';  # 过滤空类型
            """

            cursor.execute(sql)  # 执行SQL查询
            result = cursor.fetchone()  # 获取查询结果
            return result[0] if result else 0  # 返回类型总数，如果没有结果则返回0

        except Exception as e:  # 捕获所有可能的异常
            print(f"获取电影类型总数时出错: {str(e)}")  # 打印错误信息
            return 0  # 发生错误时返回0

        finally:  # 确保资源正确释放
            if 'conn' in locals():  # 如果连接已创建
                cursor.close()  # 关闭数据库游标
                conn.close()  # 关闭数据库连接 